import * as dateformat from 'dateformat'

export enum CmdType {
    HEART = 101,
    SYSTEM = 0,
    LOGIN = 1,
    CHAT = 2
}

export class ClientHolders {

    readonly clients: Set<any>; // 用户列表

    constructor(...client: any[]) {
        this.clients = new Set();

        if (client && client.length > 0) {
            client.forEach(item => this.clients.add(client))
        }
    }

    size(): number {
        return this.clients.size;
    }


    public hasClient(client: any): boolean {
        return this.clients.has(client);
    }

    addClient(client: any): boolean {

        if (this.clients.has(client)) {
            return false;
        }

        this.clients.add(client);
        return true;
    }

    removeClient(client: any): boolean {

        if (!this.clients.has(client)) {
            return false;
        }
        this.clients.delete(client);
        return true;
    }


    send(msg: any) {
        if (this.clients.size > 0) {
            this.clients.forEach(client => {
                client.send(JSON.stringify(msg))
            });
        }

    }



}

export class ClientManager {

    readonly clientMaps: Map<string, ClientHolders>;

    constructor() {
        this.clientMaps = new Map();
    }

    addClient(name: string, client: any): boolean {
        let clientHolder = this.clientMaps.get(name);

        if (!clientHolder) {
            clientHolder = new ClientHolders();
            this.clientMaps.set(name, clientHolder);
        }
        const res = clientHolder.addClient(client);

        if (res) {
            this.pushOnlineMessage();
            this.pushOnlineListMessage(name);
        }

        return res;
    }

    removeClient(name: string, client: any): boolean {

        let clientHolder = this.clientMaps.get(name);

        if (!clientHolder) {
            return false;
        }

        const res = clientHolder.removeClient(client);
        if (res && clientHolder.size() === 0) {
            this.clientMaps.delete(name);
        }

        if (res) {
            this.pushOnlineMessage();
            this.pushOnlineListMessage(name);
        }
        return res;

    }

    send(callback: (name: string, cliens: ClientHolders) => void) {

        this.clientMaps.forEach((c, n) => {
            callback(n, c)
        })
    }
    pushOnlineMessage() {
        if(this.clientMaps.size==0){
            return ;
        }
        const onlineMsg = {
            cmdType: 0,
            online: this.clientMaps.size,
            type: 2,
            sendTime: dateformat(new Date(), "yyyy-MM-dd HH:mm:ss")
        }
        this.send((n, c) => {
            c.send(onlineMsg);
        })
    }

    pushOnlineListMessage(name: string) {
        if(this.clientMaps.size==0){
            return ;
        }
        const names: string[] = [];
        this.clientMaps.forEach((_, n) => {
            names.push(n)
        })
        const onlineMsg = {
            cmdType: 0,
            onlineList: names,
            type: 3,
            sendTime: dateformat(new Date(), "yyyy-MM-dd HH:mm:ss")
        }
        this.send((n, c) => {
            c.send(onlineMsg);
        })
    }
}
